package com.njxxted.activiti.modules.process.cmd;

import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.cmd.NeedsActiveTaskCmd;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * 描述：回退到指定节点 执行命令
 * <p>
 * 作者：Ostrich Hu
 * 时间：2019/9/6 16:31 星期五
 */
public class RollbackNodeCmd extends NeedsActiveTaskCmd<Void> {

    private static final long serialVersionUID = 1751035055387148532L;

    private static Logger logger = LoggerFactory.getLogger(RollbackNodeCmd.class);

    //退回原因
    public String deleteReason;

    //退回目标节点
    public FlowNode flowNode;

    //是否是开始节点
    public boolean isStarted;

    public RollbackNodeCmd(String taskId) {
        super(taskId);
    }

    @Override
    protected Void execute(CommandContext commandContext, TaskEntity currentTask) {
        String executionId = currentTask.getExecutionId();

        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
        taskEntityManager.deleteTask(currentTask, deleteReason, false, false);

        FlowNode targetNode = this.getTargetNode(flowNode, isStarted);
        ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findById(executionId);

        if (targetNode == null) {
            throw new ActivitiException("回退错误，目标节点不能为空");
        }
        // 获取目标节点的来源连线
        List<SequenceFlow> flows = targetNode.getIncomingFlows();
        if (flows == null || flows.isEmpty()) {
            throw new ActivitiException("回退错误，目标节点没有来源连线");
        }
        // 随便选一条连线来执行，时当前执行计划为，从连线流转到目标节点，实现跳转
//        executionEntity.setCurrentFlowElement(flows.get(0));
//        commandContext.getAgenda().planTakeOutgoingSequenceFlowsOperation(executionEntity, true);
        //将返回目标节点设置为当前执行的节点
        executionEntity.setCurrentFlowElement(targetNode);
        commandContext.getAgenda().planContinueProcessOperation(executionEntity);
        return null;
    }

    private FlowNode getTargetNode(FlowNode flowNode, boolean isStarted) {
        logger.debug("回退到节点：[{}]", flowNode.getName());
        if (isStarted && flowNode.getOutgoingFlows().size() != 1) {
            throw new IllegalStateException("start activity outgoing transitions cannot more than 1, now is : " + flowNode.getOutgoingFlows().size());
        }

        //
//        SequenceFlow sequenceFlow = flowNode.getOutgoingFlows().get(0);
//        FlowNode targetActivity = (FlowNode) sequenceFlow.getTargetFlowElement();

        if (!(flowNode instanceof UserTask)) {
            logger.info("first activity is not userTask, just skip");
            return null;
        }
        return flowNode;
    }

    @Override
    public String getSuspendedTaskException() {
        return "挂起的任务不能跳转";
    }
}
